﻿#include "MdbPrimaryKeys.h"
#include "MdbTables.h"
#include "Utility.h"
#include <string.h>

using std::unordered_set;


namespace mdb
{
	TickPrimaryKey::TickPrimaryKey(TickTable* table, size_t buckets)
		:m_Table(table), m_Index(buckets)
	{
	}
	Tick* TickPrimaryKey::Select(const Int64Type& TradingDay, const ExchangeIDType& ExchangeID, const InstrumentIDType& InstrumentID, const Int64Type& UpdateTs)
	{
		t_CompareTick.TradingDay = TradingDay;
		Strcpy(t_CompareTick.ExchangeID, ExchangeID);
		Strcpy(t_CompareTick.InstrumentID, InstrumentID);
		t_CompareTick.UpdateTs = UpdateTs;
		
		std::shared_lock guard(m_Table->m_SharedMutex);
		auto it = m_Index.find(&t_CompareTick);
		if (it == m_Index.end())
		{
			return nullptr;
		}
		return *it;
	}
	std::pair<TickPrimaryKey::iterator, TickPrimaryKey::iterator> TickPrimaryKey::SelectAll()
	{
		std::shared_lock guard(m_Table->m_SharedMutex);
		return std::pair(m_Index.begin(), m_Index.end());
	}
	bool TickPrimaryKey::Insert(Tick* const record)
	{
		return m_Index.insert(record).second;
	}
	void TickPrimaryKey::Erase(Tick* const  record)
	{
		m_Index.erase(record);
	}
	bool TickPrimaryKey::CheckInsert(Tick* const record)
	{
		return m_Index.find(record) == m_Index.end();
	}
	bool TickPrimaryKey::CheckUpdate(const Tick* const oldRecord, const Tick* const newRecord)
	{
		return TickEqualForTickPrimaryKey()(oldRecord, newRecord);
	}

	BarPrimaryKey::BarPrimaryKey(BarTable* table, size_t buckets)
		:m_Table(table), m_Index(buckets)
	{
	}
	Bar* BarPrimaryKey::Select(const Int64Type& TradingDay, const ExchangeIDType& ExchangeID, const InstrumentIDType& InstrumentID, const Int64Type& UpdateTs)
	{
		t_CompareBar.TradingDay = TradingDay;
		Strcpy(t_CompareBar.ExchangeID, ExchangeID);
		Strcpy(t_CompareBar.InstrumentID, InstrumentID);
		t_CompareBar.UpdateTs = UpdateTs;
		
		std::shared_lock guard(m_Table->m_SharedMutex);
		auto it = m_Index.find(&t_CompareBar);
		if (it == m_Index.end())
		{
			return nullptr;
		}
		return *it;
	}
	std::pair<BarPrimaryKey::iterator, BarPrimaryKey::iterator> BarPrimaryKey::SelectAll()
	{
		std::shared_lock guard(m_Table->m_SharedMutex);
		return std::pair(m_Index.begin(), m_Index.end());
	}
	bool BarPrimaryKey::Insert(Bar* const record)
	{
		return m_Index.insert(record).second;
	}
	void BarPrimaryKey::Erase(Bar* const  record)
	{
		m_Index.erase(record);
	}
	bool BarPrimaryKey::CheckInsert(Bar* const record)
	{
		return m_Index.find(record) == m_Index.end();
	}
	bool BarPrimaryKey::CheckUpdate(const Bar* const oldRecord, const Bar* const newRecord)
	{
		return BarEqualForBarPrimaryKey()(oldRecord, newRecord);
	}

}
